#include "base.h"

#include "list.h"
#include "mainMenuScene.h"
#include "mainMenuHud.h"

#ifndef _WIN32
#include <unistd.h>
#else
void usleep(unsigned int nanosec)
{
    Sleep(nanosec / 1000);
}
#endif

// --------------- USER INTERFACE VARIABLES -----------------

// Window settings
int windowID;               // Glut window ID (for display)
GLUI *glui;                 // Glui window (for controls)
int Win[2];                 // window (x,y) size

// ***********  FUNCTION HEADER DECLARATIONS ****************
List<Scene> SceneList;
string currentScene;

// Initialization functions
void initGlut(char* winName);
//void initGlui();
void initGl();

// Callbacks for handling events in glut
//void animate();
void display(void);
void myReshape(int w, int h);
void keyboardInput(GLubyte key, GLint x, GLint y);

// Callback for handling events in glui
//void GLUI_Control(int id);

// Return the current system clock (in seconds)
//double getTime();

int main(int argc, char** argv)
{
    // Process program arguments
    if(argc != 3) {
        printf("Usage: demo [width] [height]\n");
        printf("Using 600x400 window by default...\n");
        Win[0] = 600;
        Win[1] = 400;
    } else {
        Win[0] = atoi(argv[1]);
        Win[1] = atoi(argv[2]);
    }

//	atexit(cleanup);

    // Initialize glut, glui, and opengl
    glutInit(&argc, argv);
    initGlut(argv[0]);
//    initGlui();
    initGl();
 
	currentScene = "";

	MainMenuScene* tempScene = new MainMenuScene("Main Scene");
	tempScene->Activate();
	SceneList.Add(tempScene, "Main");	


	MainMenuHud* tempHud = new MainMenuHud();
	tempHud->Activate();
	tempScene->AddHud(tempHud, "MainHud");

	cout << "Name of first item: " << SceneList["Main"]->getName() << endl;

	// Invoke the standard GLUT main event loop
    glutMainLoop();

    return 0;         // never reached
}

// Initialize glut and create a window with the specified caption 
void initGlut(char* winName)
{
    // Set video mode: double-buffered, color, depth-buffered
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

    // Create window
    glutInitWindowPosition (0, 0);
    glutInitWindowSize(Win[0],Win[1]);
    windowID = glutCreateWindow(winName);

    // Setup callback functions to handle events
    glutReshapeFunc(myReshape); // Call myReshape whenever window resized
    glutDisplayFunc(display);   // Call display whenever new frame needed 
	glutKeyboardFunc(keyboardInput);
}

// Performs most of the OpenGL intialization
void initGl(void)
{
    // glClearColor (red, green, blue, alpha)
    // Ignore the meaning of the 'alpha' value for now
    glClearColor(0.7f,0.7f,0.9f,1.0f);
}

void display(void)
{

   /* Clear the window. */
   glClearColor(0.0, 0.0, 0.0, 0.0);
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	//draw the scenes that are active
   for(int i = 0; i < SceneList.Length(); i++)
		if(SceneList[i]->Active())
			SceneList[i]->Draw();

   glutSwapBuffers();
}


void myReshape(int w, int h)
// Handles the window being resized by updating the viewport
// and projection matrices
{
    // Setup projection matrix for new window
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(-w/2, w/2, -h/2, h/2);

    // Update OpenGL viewport and internal variables
    glViewport(0,0, w,h);
    Win[0] = w;
    Win[1] = h;
}

void keyboardInput(GLubyte key, GLint x, GLint y)
{
	switch (key) 
	{
		case 27:    /* Esc - Quits the program. */
			printf("done.\n");
			exit(1);
			break;
//   case '1':
		default:
			break;
	} //switch

	//send keyboard input to all active scenes
	for(int i = 0; i < SceneList.Length(); i++)
		if(SceneList[i]->Active())
			SceneList[i]->keyboardInput(key, x, y);
}

void DeactivateAllScenes()
{
	//deactivate all scenes
	for(int i = 0; i < SceneList.Length(); i++)
		SceneList[i]->Deactivate();
}

void ActivateScene(string Name)
{
	//deactivate the current scene
	if(currentScene != "")
		SceneList[currentScene]->Deactivate();

	//activate the new scene
	SceneList[Name]->Activate();

	//note the "new" current scene
	currentScene = Name;
}